package barinadroid.game;

import org.andengine.entity.Entity;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import android.util.Log;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.FixtureDef;

public abstract class GameEntity extends Entity
{
	public enum EntityIdentity
	{
		STATIC(STATIC_FIXTURE_DEF), GENERAL(GENERAL_FIXTURE_DEF), PLAYER(PLAYER_FIXTURE_DEF), ENEMY(ENEMY_FIXTURE_DEF), BULLET(BULLET_FIXTURE_DEF), ENEMY_BULLET(BULLET_FIXTURE_DEF);
		//, ENEMY_BULLET(ENEMY_BULLET_FIXTURE_DEF);
		final FixtureDef def;

		EntityIdentity(FixtureDef def)
		{
			this.def = def;
		}

		public FixtureDef getFixtureDef()
		{
			return this.def;
		}

		@Override
		public String toString()
		{
			switch (this)
			{
				case STATIC:
					return "Static";
				case GENERAL:
					return "General";
				case PLAYER:
					return "Player";
				case ENEMY:
					return "Enemy";
				case BULLET:
					return "Bullet";
				case ENEMY_BULLET:
					return "Enemy Bullet";
				default:
					return "UNKNOWN";
			}
		}
	}

	// /* The categories. */
	// public static final short CATEGORYBIT_GENERAL = 1;// 0x0001
	// public static final short CATEGORYBIT_PLAYER = 2;// 0x0002
	// public static final short CATEGORYBIT_ENEMY = 4;// 0x0004
	// public static final short CATEGORYBIT_BULLET = 8;// 0x0008
	// public static final short CATEGORYBIT_ENEMY_BULLET = 16;// 0x0016
	// /* And what should collide with what. */
	// public static final short MASKBITS_GENERAL = CATEGORYBIT_ENEMY +
	// CATEGORYBIT_GENERAL + CATEGORYBIT_PLAYER + CATEGORYBIT_BULLET +
	// CATEGORYBIT_ENEMY_BULLET;
	// public static final short MASKBITS_PLAYER = CATEGORYBIT_GENERAL +
	// CATEGORYBIT_ENEMY + CATEGORYBIT_ENEMY_BULLET;
	// public static final short MASKBITS_ENEMY = CATEGORYBIT_ENEMY +
	// CATEGORYBIT_BULLET + CATEGORYBIT_GENERAL + CATEGORYBIT_PLAYER;
	// public static final short MASKBITS_BULLET = CATEGORYBIT_ENEMY +
	// CATEGORYBIT_ENEMY_BULLET + CATEGORYBIT_GENERAL;
	// public static final short MASKBITS_ENEMY_BULLET = CATEGORYBIT_PLAYER +
	// CATEGORYBIT_BULLET + CATEGORYBIT_GENERAL;
	public static final FixtureDef STATIC_FIXTURE_DEF = PhysicsFactory.createFixtureDef(0.0f, 0.0f, 0.0f);
	// public static final FixtureDef GENERAL_FIXTURE_DEF =
	// PhysicsFactory.createFixtureDef(.25f, .25f, .25f, false,
	// CATEGORYBIT_GENERAL, MASKBITS_GENERAL, (short)0);
	// public static final FixtureDef PLAYER_FIXTURE_DEF =
	// PhysicsFactory.createFixtureDef(.25f, .25f, .25f, false,
	// CATEGORYBIT_PLAYER, MASKBITS_PLAYER, (short)0);
	// public static final FixtureDef ENEMY_FIXTURE_DEF =
	// PhysicsFactory.createFixtureDef(.25f, .25f, .25f, false,
	// CATEGORYBIT_ENEMY, MASKBITS_ENEMY, (short)0);
	// public static final FixtureDef BULLET_FIXTURE_DEF =
	// PhysicsFactory.createFixtureDef(.25f, .25f, .25f, false,
	// CATEGORYBIT_BULLET, MASKBITS_BULLET, (short)0);
	// public static final FixtureDef ENEMY_BULLET_FIXTURE_DEF =
	// PhysicsFactory.createFixtureDef(.25f, .25f, .25f, false,
	// CATEGORYBIT_ENEMY_BULLET, MASKBITS_ENEMY_BULLET, (short)0);
	public static final FixtureDef GENERAL_FIXTURE_DEF = PhysicsFactory.createFixtureDef(.25f, .25f, .25f);
	public static final FixtureDef PLAYER_FIXTURE_DEF = PhysicsFactory.createFixtureDef(.25f, .25f, .25f);
	public static final FixtureDef ENEMY_FIXTURE_DEF = PhysicsFactory.createFixtureDef(.25f, .25f, .25f);
	public static final FixtureDef BULLET_FIXTURE_DEF = PhysicsFactory.createFixtureDef(.25f, .25f, .25f);
	//public static final FixtureDef ENEMY_BULLET_FIXTURE_DEF = PhysicsFactory.createFixtureDef(.25f, .25f, .25f);
	// public final FixtureDef FIX_DEF = PhysicsFactory.createFixtureDef(.25f,
	// .25f, .25f);
	protected Rectangle sprite;
	protected Body body;
	private boolean active;
	private EntityIdentity identity;

	public Rectangle getSprite()
	{
		return this.sprite;
	}

	// abstract void setBody(FixtureDef def);
	abstract void setBody(EntityIdentity identity);

	public Body getBody()
	{
		return this.body;
	}

	public Vector2 getCenter()
	{
		Vector2 result = new Vector2();
		result.x = this.sprite.getX() + getSize().width * .5f;
		result.y = this.sprite.getY() + getSize().height * .5f;
		return result;
	}

	public void setExactPosition(float x, float y)
	{
		this.body.setTransform(x / 32, y / 32, 0);
	}

	@Override
	public void setPosition(org.andengine.entity.IEntity pOtherEntity)
	{
		try
		{
			setPosition((GameEntity)pOtherEntity);
		}
		catch(ClassCastException e)
		{
			Log.e("GameEntity", "ClassCastException in setPosition. typically because you tried to cast Entity to GameEntity which is wrong.");
		}
	}

	@Override
	public void setPosition(float pX, float pY)
	{
		this.setExactPosition(pX, pY);
	}

	// public FixtureDef getFixtureDef()
	// {
	// return this.FIX_DEF;
	// }
	/***
	 * Will set the position to the center of a giver {@link GameEntity} object.
	 * 
	 * @param entity
	 *            The object to pull center point from.
	 */
	public void setPosition(GameEntity entity)
	{
		setExactPosition(entity.getCenter().x, entity.getCenter().y);
	}

	public float getAngle()
	{
		return getBody().getAngle();
	}

	public void setAngle(float rad)
	{
		getBody().setTransform(getBody().getWorldCenter(), rad);
	}

	protected void setEntityIdentity(EntityIdentity identity)
	{
		this.identity = identity;
	}

	public EntityIdentity getIdentity()
	{
		return this.identity;
	}

	public boolean isActive()
	{
		return active;
	}

	public void setActive(boolean active)
	{
		setEnabled(this.active = active);
	}

	private void setEnabled(boolean enable)
	{
		if(getSprite() != null)
			getSprite().setVisible(enable);
		if(getBody() != null)
			getBody().setActive(enable);
	}

	public Size getSize()
	{
		return new Size(sprite.getWidth(), sprite.getHeight());
	}
}